/* **********************************************************************************
 *
 * Copyright (c) Ascend.NET Project. All rights reserved.
 *
 * This source code is subject to terms and conditions of the Shared Source License
 * for Ascend. A copy of the license can be found in the License.html file
 * at the root of this distribution. If you can not locate the Shared Source License
 * for Ascend, please send an email to ascend_adm@hotmail.com.
 * By using this source code in any fashion, you are agreeing to be bound by
 * the terms of the Shared Source License for Ascend.NET.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * **********************************************************************************/

using System;
using System.ComponentModel;
using System.Drawing;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Windows.Forms;
using Ascend.Resources;
using System.Drawing.Drawing2D;
using System.ComponentModel.Design;

namespace Ascend.Windows.Forms
{
    /// <summary>
    /// Represents a gradient splitter control that enables the user to resize docked controls.
    /// </summary>
    [ComVisible(true)]
    [DefaultEvent("GradientSplitterMoved")]
    [ClassInterface(ClassInterfaceType.AutoDispatch)]
    [DefaultProperty("Dock")]
    [ToolboxBitmap(typeof(GradientSplitter), "GradientSplitter.ico")]
#if GENERAL_RELEASE
    [Designer(typeof(Ascend.Windows.Forms.Design.GradientSplitterDesigner), typeof(IDesigner))]
#else
    [Designer("Ascend.Windows.Forms.Design.GradientSplitterDesigner, Ascend.Design.v1.5, Culture=neutral, PublicKeyToken=5123e2ac4258b06a", typeof(IDesigner))]
#endif
    [DesignerCategory("Form")]
    [ResourceDescriptionAttribute("GradientSplitterDescription")]
    public class GradientSplitter : Control
    {
        private const int DRAW_SPLITTER_END = 3;
        private const int DRAW_SPLITTER_MOVE = 2;
        private const int DRAW_SPLITTER_START = 1;
        private const int DEFAULT_SPLITTER_WIDTH = 5;

        private Point _anchor;
        private int _initTargetSize;
        private int _lastSplitterSize;
        private int _maxSize;
        private int _minExtra;
        private int _minSize;
        private int _splitterSize;
        private Control _splitTarget;
        private GradientSplitterMessageFilter _gradientSplitterMessageFilter;
        private int _splitterThickness;
        private GradientSplitBarRender _gradientSplitBarRender;
        private bool _showBackground;
        private bool _disposed;

        /// <summary>
        /// Occurs when the Alpha property changes.
        /// </summary>
        [ResourceDescriptionAttribute("AlphaChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameAlphaChanged")]
        public event EventHandler AlphaChanged;

        /// <summary>
        /// Occurs when the AntiAlias property changes.
        /// </summary>
        [ResourceDescriptionAttribute("AntiAliasChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameAntiAliasChanged")]
        public event EventHandler AntiAliasChanged;

        /// <summary>
        /// Occurs when the Border property changes.
        /// </summary>
        [ResourceDescriptionAttribute("BorderChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameBorderChanged")]
        public event EventHandler BorderChanged;

        /// <summary>
        /// Occurs when the BorderColor property changes.
        /// </summary>
        [ResourceDescriptionAttribute("BorderColorChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameBorderColorChanged")]
        public event EventHandler BorderColorChanged;
        
        /// <summary>
        /// Occurs when the BumpCount property changes.
        /// </summary>
        [ResourceDescriptionAttribute("BumpCountChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameBumpCountChanged")]
        public event EventHandler BumpCountChanged;

        /// <summary>
        /// Occurs when the GradientLowColor property changes.
        /// </summary>
        [ResourceDescriptionAttribute("GradientLowColorChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameGradientLowColorChanged")]
        public event EventHandler GradientLowColorChanged;

        /// <summary>
        /// Occurs when the GradientHighColor property changes.
        /// </summary>
        [ResourceDescriptionAttribute("GradientHighColorChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameGradientHighColorChanged")]
        public event EventHandler GradientHighColorChanged;

        /// <summary>
        /// Occurs when the GradientMode property changes.
        /// </summary>
        [ResourceDescriptionAttribute("GradientModeChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameGradientModeChanged")]
        public event EventHandler GradientModeChanged;

        /// <summary>
        /// Occurs when the CornerRadius property changes.
        /// </summary>
        [ResourceDescriptionAttribute("CornerRadiusChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameCornerRadiusChanged")]
        public event EventHandler CornerRadiusChanged;

        /// <summary>
        /// This event is not used in this class.
        /// </summary>
        [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
        public new event EventHandler BackgroundImageChanged
        {
            add
            {
                base.BackgroundImageChanged += value;

            }

            remove
            {
                base.BackgroundImageChanged -= value;

            }

        }

        /// <summary>
        /// This event is not used in this class.
        /// </summary>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackgroundImageLayoutChanged
        {
            add
            {
                base.BackgroundImageLayoutChanged += value;

            }

            remove
            {
                base.BackgroundImageLayoutChanged -= value;

            }

        }

        /// <summary>
        /// Specifies the number of bumps to be drawn on the split bar.
        /// </summary>
        /// <remarks>
        /// <para>
        /// Negative numbers will be converted to 0. If a bump count number is greater than the surface allows, only the amount that can be drawn will be drawn.
        /// </para>
        /// </remarks>
        /// <value>
        /// <para>
        /// System.Int32
        /// </para>
        /// <para>
        /// This property is read/write.
        /// </para>
        /// </value>
        [DescriptionAttribute("BumpCountDescription"), CategoryAttribute("Appearance"), ResourceDisplayName("DisplayNameBumpCount"), DefaultValueAttribute(9), BrowsableAttribute(true)]
        public int BumpCount
        {
            get
            {
                return this._gradientSplitBarRender.BumpCount;

            }

            set
            {
                if (value < 0) value = 0;

                if (value == this._gradientSplitBarRender.BumpCount)
                {
                    return;

                }

                this._gradientSplitBarRender.BumpCount = value;

                base.Invalidate();

                this.OnBumpCountChanged(new EventArgs());

            }

        }

        /// <summary>
        /// This event is not used in this class.
        /// </summary>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler Enter
        {
            add
            {
                base.Enter += value;

            }

            remove
            {
                base.Enter -= value;

            }

        }

        /// <summary>
        /// This event is not used in this class.
        /// </summary>
        [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
        public new event EventHandler FontChanged
        {
            add
            {
                base.FontChanged += value;

            }

            remove
            {
                base.FontChanged -= value;

            }

        }

        /// <summary>
        /// This event is not used in this class.
        /// </summary>
        [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
        public new event EventHandler ForeColorChanged
        {
            add
            {
                base.ForeColorChanged += value;

            }

            remove
            {
                base.ForeColorChanged -= value;

            }

        }

        /// <summary>
        /// This event is not used in this class.
        /// </summary>
        [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
        public new event EventHandler ImeModeChanged
        {
            add
            {
                base.ImeModeChanged += value;

            }

            remove
            {
                base.ImeModeChanged -= value;

            }

        }

        /// <summary>
        /// This event is not used in this class.
        /// </summary>
        [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
        public new event KeyEventHandler KeyDown
        {
            add
            {
                base.KeyDown += value;

            }

            remove
            {
                base.KeyDown -= value;

            }

        }

        /// <summary>
        /// This event is not used in this class.
        /// </summary>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event KeyPressEventHandler KeyPress
        {
            add
            {
                base.KeyPress += value;

            }

            remove
            {
                base.KeyPress -= value;

            }

        }

        /// <summary>
        /// This event is not used in this class.
        /// </summary>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event KeyEventHandler KeyUp
        {
            add
            {
                base.KeyUp += value;

            }

            remove
            {
                base.KeyUp -= value;

            }

        }

        /// <summary>
        /// This event is not relevant to this class.
        /// </summary>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler Leave
        {
            add
            {
                base.Leave += value;

            }

            remove
            {
                base.Leave -= value;

            }

        }

        /// <summary>
        /// Occurs when the gradient splitter control is moved. 
        /// </summary>
        public event EventHandler<GradientSplitterEventArgs> GradientSplitterMoved;

        /// <summary>
        /// Occurs when the gradient splitter control is in the process of moving. 
        /// </summary>
        public event EventHandler<GradientSplitterEventArgs> GradientSplitterMoving;

        /// <summary>
        /// This event is not used in this class.
        /// </summary>
        [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
        public new event EventHandler TabStopChanged
        {
            add
            {
                base.TabStopChanged += value;

            }

            remove
            {
                base.TabStopChanged -= value;

            }

        }

        /// <summary>
        /// This event is not used in this class.
        /// </summary>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler TextChanged
        {
            add
            {
                base.TextChanged += value;

            }

            remove
            {
                base.TextChanged -= value;

            }

        }

        /// <summary>
        /// Gets or sets if the background should be shown on the control.
        /// </summary>
        /// <remarks>
        /// True by default.
        /// </remarks>
        /// <returns>
        /// true if should be shown; otherwise, false. 
        /// </returns>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("ShowBackgroundDescription"), ResourceDisplayName("DisplayNameShowBackground"), DefaultValue(true)]
        public bool ShowBackground
        {
            get 
            { 
                return this._showBackground;
            
            }

            set 
            { 
                this._showBackground = value;
            
            }

        }

        /// <summary>
        /// This property is not used in this class.
        /// </summary>
        /// <returns>
        /// true if enabled; otherwise, false. 
        /// </returns>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new bool TabStop
        {
            get
            {
                return base.TabStop;

            }

            set
            {
                base.TabStop = value;

            }

        }

        /// <summary>
        /// This property is not used in this class.
        /// </summary>
        /// <returns>
        /// A string.
        /// </returns>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), Bindable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override string Text
        {
            get
            {
                return base.Text;

            }

            set
            {
                base.Text = value;

            }

        }

        /// <summary>
        /// This property is not used in this class.
        /// </summary>
        /// <returns>
        /// true if enabled; otherwise, false. 
        /// </returns>
        [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
        public override bool AllowDrop
        {
            get
            {
                return base.AllowDrop;

            }

            set
            {
                base.AllowDrop = value;

            }

        }

        /// <summary>
        /// This property is not used in this class.
        /// </summary>
        /// <returns>
        /// One of the <see cref="T:System.Windows.Forms.AnchorStyles"></see> values.
        /// </returns>
        [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DefaultValue(0)]
        public override AnchorStyles Anchor
        {
            get
            {
                return AnchorStyles.None;

            }

            set
            {
            }

        }

        /// <summary>
        /// This property is not used in this class.
        /// </summary>
        /// <returns>
        /// An <see cref="T:System.Drawing.Image"></see>.
        /// </returns>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public override Image BackgroundImage
        {
            get
            {
                return base.BackgroundImage;

            }

            set
            {
                base.BackgroundImage = value;

            }

        }

        /// <summary>
        /// This property is not used in this class.
        /// </summary>
        /// <returns>
        /// One of the <see cref="T:System.Windows.Forms.ImageLayout"></see> values.
        /// </returns>
        [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
        public override ImageLayout BackgroundImageLayout
        {
            get
            {
                return base.BackgroundImageLayout;

            }

            set
            {
                base.BackgroundImageLayout = value;

            }

        }

        /// <summary>
        /// Gets or sets the default cursor for the control.
        /// </summary>
        /// <returns>
        /// An object of type <see cref="T:System.Windows.Forms.Cursor"></see> representing the current default cursor.
        /// </returns>
        protected override Cursor DefaultCursor
        {
            get
            {
                switch (this.Dock)
                {
                    case DockStyle.Top:
                    case DockStyle.Bottom:
                        return Cursors.HSplit;

                    case DockStyle.Left:
                    case DockStyle.Right:
                        return Cursors.VSplit;

                }

                return base.DefaultCursor;

            }

        }

        /// <summary>
        /// Gets the default Input Method Editor (IME) mode supported by this control.
        /// </summary>
        protected override System.Windows.Forms.ImeMode DefaultImeMode
        {
            get
            {
                return System.Windows.Forms.ImeMode.Disable;

            }

        }

        /// <summary>
        /// Gets the default size of the control.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.Drawing.Size"></see> that represents the default size of the control.
        /// </returns>
        protected override Size DefaultSize
        {
            get
            {
                return new Size(5, 5);

            }

        }

        /// <summary>
        /// Gets or sets which GradientSplitter borders are docked to its parent control and determines how a GradientSplitter is resized with its parent.
        /// </summary>
        /// <returns>
        /// One of the <see cref="T:System.Windows.Forms.DockStyle"></see> values. The default is <see cref="F:System.Windows.Forms.DockStyle.Left"></see>.
        /// </returns>
        [Localizable(true), DefaultValue(3)]
        public override DockStyle Dock
        {
            get
            {
                return base.Dock;

            }

            set
            {
                if (((value != DockStyle.Top) && (value != DockStyle.Bottom)) && ((value != DockStyle.Left) && (value != DockStyle.Right)))
                {
                    throw new ArgumentException("SplitterInvalidDockEnum");

                }

                base.Dock = value;

                switch (this.Dock)
                {
                    case DockStyle.Top:
                    case DockStyle.Bottom:
                        this._gradientSplitBarRender.Direction = GradientSplitBarDirection.Horizontal;

                        if (this._splitterThickness != -1)
                        {
                            base.Height = this._splitterThickness;
                            return;

                        }
                        return;

                    case DockStyle.Left:
                    case DockStyle.Right:
                        this._gradientSplitBarRender.Direction = GradientSplitBarDirection.Vertical;

                        if (this._splitterThickness != -1)
                        {
                            base.Width = this._splitterThickness;

                        }
                        return;

                }

            }

        }

        /// <summary>
        /// This property is not used in this class.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.Drawing.Font"></see>.
        /// </returns>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public override System.Drawing.Font Font
        {
            get
            {
                return base.Font;

            }

            set
            {
                base.Font = value;

            }

        }

        /// <summary>
        /// This property is not used in this class.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.Drawing.Color"></see>.
        /// </returns>
        [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
        public override Color ForeColor
        {
            get
            {
                return base.ForeColor;

            }

            set
            {
                base.ForeColor = value;

            }

        }

        private bool Horizontal
        {
            get
            {
                DockStyle dockStyle = this.Dock;
                if (dockStyle != DockStyle.Left)
                {
                    return (dockStyle == DockStyle.Right);

                }

                return true;

            }

        }

        /// <summary>
        /// This property is not used in this class.
        /// </summary>
        /// <returns>
        /// One of the <see cref="T:System.Windows.Forms.ImeMode"></see> values.
        /// </returns>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new System.Windows.Forms.ImeMode ImeMode
        {
            get
            {
                return base.ImeMode;

            }

            set
            {
                base.ImeMode = value;

            }

        }

        /// <summary>
        /// Gets or sets the minimum distance that must remain between the GradientSplitter control and the edge of the opposite side of the container (or the closest control docked to that side). 
        /// </summary>
        /// <returns>
        /// The minimum distance, in pixels, between the GradientSplitter control and the edge of the opposite side of the container (or the closest control docked to that side). The default is 25.
        /// </returns>
        [Localizable(true), DefaultValue(25)]
        public int MinExtra
        {
            get
            {
                return this._minExtra;

            }

            set
            {
                if (value < 0)
                {
                    value = 0;

                }

                this._minExtra = value;

            }

        }

        /// <summary>
        /// Gets or sets the minimum distance that must remain between the GradientSplitter control and the container edge that the control is docked to.
        /// </summary>
        /// <returns>
        /// The minimum distance, in pixels, between the GradientSplitter control and the container edge that the control is docked to. The default is 25.
        /// </returns>
        [Localizable(true), DefaultValue(25)]
        public int MinSize
        {
            get
            {
                return this._minSize;

            }

            set
            {
                if (value < 0)
                {
                    value = 0;

                }

                this._minSize = value;

            }

        }

        /// <summary>
        /// Gets or sets the distance between the GradientSplitter control and the container edge that the control is docked to. 
        /// </summary>
        /// <returns>
        /// The distance, in pixels, between the GradientSplitter control and the container edge that the control is docked to. If the GradientSplitter control is not bound to a control, the value is -1.
        /// </returns>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)]
        public int SplitPosition
        {
            get
            {
                if (this._splitterSize == -1)
                {
                    this._splitterSize = this.CalcutateSplitterSize();

                }

                return this._splitterSize;

            }

            set
            {
                GradientSplitterData gradientSplitterData = this.CalculateSplitterBounds();
                if (value > this._maxSize)
                {
                    value = this._maxSize;

                }

                if (value < this._minSize)
                {
                    value = this._minSize;

                }

                this._splitterSize = value;
                this.DrawSplitterBar(DRAW_SPLITTER_END);

                if (gradientSplitterData.target == null)
                {
                    this._splitterSize = -1;

                }
                else
                {
                    Rectangle rectangle = gradientSplitterData.target.Bounds;
                    switch (this.Dock)
                    {
                        case DockStyle.Top:
                            rectangle.Height = value;
                            break;

                        case DockStyle.Bottom:
                            rectangle.Y += rectangle.Height - this._splitterSize;
                            rectangle.Height = value;
                            break;

                        case DockStyle.Left:
                            rectangle.Width = value;
                            break;

                        case DockStyle.Right:
                            rectangle.X += rectangle.Width - this._splitterSize;
                            rectangle.Width = value;
                            break;

                    }

                    gradientSplitterData.target.Bounds = rectangle;

                    Application.DoEvents();

                    this.OnGradientSplitterMoved(new GradientSplitterEventArgs(base.Left, base.Top, base.Left + (rectangle.Width / 2), base.Top + (rectangle.Height / 2)));

                }

            }

        }

        /// <summary>
        /// Gets or sets the alpha (transparancy) level (0 - 255) of the fill of the control.
        /// </summary>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("AlphaDescription"), ResourceDisplayName("DisplayNameAlpha"), DefaultValue(255)]
        public int Alpha
        {
            get
            {
                return this._gradientSplitBarRender.Alpha;

            }

            set
            {
                if (value == this._gradientSplitBarRender.Alpha)
                {
                    return;

                }

                this._gradientSplitBarRender.Alpha = value;

                base.Invalidate();

                this.OnAlphaChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Specifies the rendering hint for the control.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Boolean . Specifies if the rendering should use antialiasing.
        /// </para>
        /// <para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("AntiAliasDescription"), ResourceDisplayName("DisplayNameAntiAlias"), DefaultValueAttribute(false)]
        public bool AntiAlias
        {
            get
            {
                return this._gradientSplitBarRender.AntiAlias;

            }

            set
            {
                if (value == this._gradientSplitBarRender.AntiAlias)
                {
                    return;

                }

                this._gradientSplitBarRender.AntiAlias = value;

                base.Invalidate();

                this.OnAntiAliasChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets the border for the control.
        /// </summary>
        /// <value>
        /// <para>
        /// Border. An object of type Border representing the control's border width characteristics.
        /// </para>
        /// <para>
        /// This property is read/write.
        /// </para>
        /// </value>
        /// <remarks>
        /// For containers such as GradientPanel and GradientCaption, the Border property gets or sets their respective border widths inside the DisplayRectangle.
        /// </remarks>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("BorderDescription"), ResourceDisplayName("DisplayNameBorder"), DefaultValueAttribute(typeof(Border), "0, 0, 0, 0")]
        public Border Border
        {
            get
            {
                return this._gradientSplitBarRender.Border;

            }

            set
            {
                if (value == this._gradientSplitBarRender.Border)
                {
                    return;

                }

                this._gradientSplitBarRender.Border = value;

                base.Invalidate();

                this.OnBorderChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets the border color(s) for the control.
        /// </summary>
        /// <value>
        /// <para>
        /// BorderColor. An object of type Border representing the control's border color characteristics.
        /// </para>
        /// <para>
        /// This property is read/write.
        /// </para>
        /// </value>
        /// <remarks>
        /// For containers such as GradientPanel and GradientCaption, the BorderColor property gets or sets their respective border colors inside the DisplayRectangle.
        /// </remarks>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("BorderColorDescription"), ResourceDisplayName("DisplayNameBorderColor"), DefaultValueAttribute(typeof(BorderColor), "Left=Color [ActiveCaption],Top=Color [ActiveCaption],Right=Color [ActiveCaption],Bottom=Color [ActiveCaption]")]
        public virtual BorderColor BorderColor
        {
            get
            {
                return this._gradientSplitBarRender.BorderColor;

            }

            set
            {
                if (value == this._gradientSplitBarRender.BorderColor)
                {
                    return;

                }

                this._gradientSplitBarRender.BorderColor = value;

                base.Invalidate();

                this.OnBorderColorChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets the corner radius for the control.
        /// </summary>
        /// <value>
        /// <para>
        /// CornerRadius. An object of type CornerRadius representing the control's corner radius characteristics.
        /// </para>
        /// <para>
        /// This property is read/write.
        /// </para>
        /// </value>
        /// <remarks>
        /// For containers such as GradientPanel and GradientCaption, the CornerRadius property gets or sets their respective corner radius inside the DisplayRectangle.
        /// </remarks>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("CornerRadiusDescription"), ResourceDisplayName("DisplayNameCornerRadious"), DefaultValueAttribute(typeof(CornerRadius), "0, 0, 0, 0")]
        public CornerRadius CornerRadius
        {
            get
            {
                return this._gradientSplitBarRender.CornerRadius;

            }

            set
            {
                if (value == this._gradientSplitBarRender.CornerRadius)
                {
                    return;

                }

                this._gradientSplitBarRender.CornerRadius = value;

                base.Invalidate();

                this.OnCornerRadiusChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets the gradient high (lighter) color for the control.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Drawing.Color . A Color that represents the gradient high color of the control.
        /// </para>
        /// <para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("GradientHighColorDescription"), ResourceDisplayName("DisplayNameGradientHighColor"), DefaultValueAttribute(typeof(Color), "Window")]
        public Color GradientHighColor
        {
            get
            {
                return this._gradientSplitBarRender.GradientHighColor;

            }

            set
            {
                if (value == this._gradientSplitBarRender.GradientHighColor)
                {
                    return;

                }

                this._gradientSplitBarRender.GradientHighColor = value;

                base.Invalidate();

                this.OnGradientHighColorChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets the gradient low (darker) color for the control.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Drawing.Color . A Color that represents the gradient low color of the control.
        /// </para>
        /// <para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("GradientLowColorDescription"), ResourceDisplayName("DisplayNameGradientLowColor"), DefaultValueAttribute(typeof(Color), "MenuBar")]
        public Color GradientLowColor
        {
            get
            {
                return this._gradientSplitBarRender.GradientLowColor;

            }

            set
            {
                if (value == this._gradientSplitBarRender.GradientLowColor)
                {
                    return;

                }

                this._gradientSplitBarRender.GradientLowColor = value;

                base.Invalidate();

                this.OnGradientLowColorChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Specifies the direction of a linear gradient.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Drawing.Drawing2D.LinearGradientMode . Specifies the direction of a linear gradient.
        /// </para>
        /// <para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("GradientModeDescription"), ResourceDisplayName("DisplayNameGradientMode"), DefaultValue(LinearGradientMode.ForwardDiagonal)]
        public LinearGradientMode GradientMode
        {
            get
            {
                return this._gradientSplitBarRender.GradientMode;

            }

            set
            {
                if (value == this._gradientSplitBarRender.GradientMode)
                {
                    return;

                }

                this._gradientSplitBarRender.GradientMode = value;

                base.Invalidate();

                this.OnGradientModeChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets how bright the high color will be starting at the highlight transition point.
        /// </summary>
        /// <remarks>
        /// 1.15 by default.
        /// </remarks>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("HighColorLuminanceDescription"), ResourceDisplayName("DisplayNameHighColorLuminance"), DefaultValue(typeof(float), "1.15")]
        public float HighColorLuminance
        {
            get
            {
                return this._gradientSplitBarRender.HighColorLuminance;

            }

            set
            {
                if (value == this._gradientSplitBarRender.HighColorLuminance)
                {
                    return;

                }

                this._gradientSplitBarRender.HighColorLuminance = value;

                base.Invalidate();

            }

        }

        /// <summary>
        /// Gets or sets if the inside edge of the border should be highlighted.
        /// </summary>
        /// <remarks>
        /// False by default.
        /// </remarks>
        /// <value>
        /// true to highlight; otherwise false
        /// </value>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("HighlightBorderDescription"), ResourceDisplayName("DisplayNameHighlightBorder"), DefaultValueAttribute(false)]
        public bool HighlightBorder
        {
            get
            {
                return this._gradientSplitBarRender.HighlightBorder;

            }

            set
            {
                if (value == this._gradientSplitBarRender.HighlightBorder)
                {
                    return;

                }

                this._gradientSplitBarRender.HighlightBorder = value;

                base.Invalidate();

            }

        }

        /// <summary>
        /// Gets or sets the highlight transition percent.
        /// </summary>
        /// <remarks>
        /// .45 by default.
        /// The location by percent of the control where the color will transition from high to low color.
        /// This value is only used in glass render mode.
        /// </remarks>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("HighlightTransitionPercentDescription"), ResourceDisplayName("DisplayNameHighlightTransitionPercent"), DefaultValueAttribute(typeof(float), ".45")]
        public float HighlightTransitionPercent
        {
            get
            {
                return this._gradientSplitBarRender.HighlightTransitionPercent;

            }

            set
            {
                if (value == this._gradientSplitBarRender.HighlightTransitionPercent)
                {
                    return;

                }

                this._gradientSplitBarRender.HighlightTransitionPercent = value;

                base.Invalidate();

            }

        }

        /// <summary>
        /// Gets or sets how bright the low color will be furthest from the highlight transition point.
        /// </summary>
        /// <remarks>
        /// 1.2 by default.
        /// </remarks>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("LowColorLuminanceDescription"), ResourceDisplayName("DisplayNameLowColorLuminance"), DefaultValue(typeof(float), "1.2")]
        public float LowColorLuminance
        {
            get
            {
                return this._gradientSplitBarRender.LowColorLuminance;

            }

            set
            {
                if (value == this._gradientSplitBarRender.LowColorLuminance)
                {
                    return;

                }

                this._gradientSplitBarRender.LowColorLuminance = value;

                base.Invalidate();

            }

        }

        /// <summary>
        /// Specifies the painting style applied to the background in a control.
        /// </summary>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("RenderModeDescription"), ResourceDisplayName("DisplayNameRenderMode"), DefaultValueAttribute(typeof(RenderMode), "Gradient")]
        public RenderMode RenderMode
        {
            get
            {
                return this._gradientSplitBarRender.RenderMode;

            }

            set
            {
                if (value == this._gradientSplitBarRender.RenderMode)
                {
                    return;

                }

                this._gradientSplitBarRender.RenderMode = value;

                base.Invalidate();

            }

        }

        /// <summary>
        /// Specifies if the background color(s) should be shown as disabled if the control's enabled property is set to false.
        /// </summary>
        /// <remarks>
        /// True by default.
        /// When a control is disabled and this property is true the background color(s) will be converted to grayscale to show that the control is not enabled.
        /// When a control is disabled and this property is false the background color(s) will not be changed.
        /// </remarks>
        /// <value>true or false</value>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("ShowDisabledBackgroundColorDescription"), ResourceDisplayName("DisplayNameShowDisabledBackgroundColor"), DefaultValueAttribute(true)]
        public bool ShowDisabledBackgroundColor
        {
            get
            {
                return this._gradientSplitBarRender.ShowDisabledBackgroundColor;

            }

            set
            {
                this._gradientSplitBarRender.ShowDisabledBackgroundColor = value;

            }

        }

        /// <summary>
        /// A static instance of the GradientSplitter class.
        /// </summary>
        static GradientSplitter()
        {
        }

        /// <summary>
        /// Initializes a new instance of the GradientSplitter class.
        /// </summary>
        public GradientSplitter()
        {
            this._gradientSplitBarRender = new GradientSplitBarRender();

            this._showBackground = true;
            this._minSize = 25;
            this._minExtra = 25;
            this._anchor = Point.Empty;
            this._splitterSize = -1;
            this._splitterThickness = 3;
            this._lastSplitterSize = -1;
            base.SetStyle(ControlStyles.Selectable, false);
            this.TabStop = false;
            this.Dock = DockStyle.Left;

        }

        /// <summary>
        /// Gets or sets if this control has mouse capture.
        /// </summary>
        internal bool HasMouseCapture
        {
            get
            {
                if (this.IsHandleCreated)
                {
                    return (UnsafeNativeMethods.GetCapture() == this.Handle);

                }

                return false;

            }

            set
            {
                if (this.HasMouseCapture != value)
                {
                    if (value)
                    {
                        UnsafeNativeMethods.SetCapture(new HandleRef(this, this.Handle));

                    }
                    else
                    {
                        SafeNativeMethods.ReleaseCapture();

                    }

                }

            }

        }

        internal virtual Control ParentInternalG
        {
            get
            {
                return this.Parent;

            }

            set
            {
                if (this.Parent != value)
                {
                    if (value != null)
                    {
                        value.Controls.Add(this);

                    }
                    else
                    {
                        this.Parent.Controls.Remove(this);

                    }

                }

            }

        }

        private GradientSplitterData CalculateSplitterBounds()
        {
            GradientSplitterData gradientSplitterData = new GradientSplitterData();
            Control control1 = this.FindTarget();
            gradientSplitterData.target = control1;

            if (control1 != null)
            {
                switch (control1.Dock)
                {
                    case DockStyle.Top:
                    case DockStyle.Bottom:
                        this._initTargetSize = control1.Bounds.Height;
                        break;

                    case DockStyle.Left:
                    case DockStyle.Right:
                        this._initTargetSize = control1.Bounds.Width;
                        break;

                }

                Control parent = this.ParentInternalG;
                Control.ControlCollection controlCollection = parent.Controls;
                int controlCount = controlCollection.Count;
                int width = 0;
                int height = 0;

                for (int i = 0; i < controlCount; i++)
                {
                    Control control3 = controlCollection[i];
                    if (control3 != control1)
                    {
                        switch (control3.Dock)
                        {
                            case DockStyle.Top:
                            case DockStyle.Bottom:
                                height += control3.Height;
                                break;

                            case DockStyle.Left:
                            case DockStyle.Right:
                                width += control3.Width;
                                break;

                        }

                    }

                }

                Size size = parent.ClientSize;
                if (this.Horizontal)
                {
                    this._maxSize = (size.Width - width) - this._minExtra;

                }
                else
                {
                    this._maxSize = (size.Height - height) - this._minExtra;

                }

                gradientSplitterData.dockWidth = width;
                gradientSplitterData.dockHeight = height;

            }

            return gradientSplitterData;

        }

        private Rectangle CalculateSplitterLine(int splitSize, int minWeight)
        {
            Rectangle rectangleSplitter = base.Bounds;
            Rectangle rectangle = this._splitTarget.Bounds;

            switch (this.Dock)
            {
                case DockStyle.Top:
                    if (rectangleSplitter.Height < minWeight)
                    {
                        rectangleSplitter.Height = minWeight;

                    }

                    rectangleSplitter.Y = rectangle.Y + splitSize;
                    return rectangleSplitter;

                case DockStyle.Bottom:
                    if (rectangleSplitter.Height < minWeight)
                    {
                        rectangleSplitter.Height = minWeight;

                    }

                    rectangleSplitter.Y = ((rectangle.Y + rectangle.Height) - splitSize) - rectangleSplitter.Height;
                    return rectangleSplitter;

                case DockStyle.Left:
                    if (rectangleSplitter.Width < minWeight)
                    {
                        rectangleSplitter.Width = minWeight;

                    }

                    rectangleSplitter.X = rectangle.X + splitSize;
                    return rectangleSplitter;

                case DockStyle.Right:
                    if (rectangleSplitter.Width < minWeight)
                    {
                        rectangleSplitter.Width = minWeight;

                    }

                    rectangleSplitter.X = ((rectangle.X + rectangle.Width) - splitSize) - rectangleSplitter.Width;
                    return rectangleSplitter;

            }

            return rectangleSplitter;

        }

        private int CalcutateSplitterSize()
        {
            Control control = this.FindTarget();
            if (control != null)
            {
                Rectangle rectangle = control.Bounds;
                switch (this.Dock)
                {
                    case DockStyle.Top:
                    case DockStyle.Bottom:
                        return rectangle.Height;

                    case DockStyle.Left:
                    case DockStyle.Right:
                        return rectangle.Width;

                }

            }

            return -1;

        }

        private void DrawSplitterBar(int mode)
        {
            if ((mode != DRAW_SPLITTER_START) && (this._lastSplitterSize != -1))
            {
                this.DrawDragSplitter(this._lastSplitterSize);
                this._lastSplitterSize = -1;

            }
            else if ((mode != DRAW_SPLITTER_START) && (this._lastSplitterSize == -1))
            {
                return;

            }
            if (mode != DRAW_SPLITTER_END)
            {
                this.DrawDragSplitter(this._splitterSize);
                this._lastSplitterSize = this._splitterSize;

            }
            else
            {
                if (this._lastSplitterSize != -1)
                {
                    this.DrawDragSplitter(this._lastSplitterSize);

                }

                this._lastSplitterSize = -1;

            }

        }

        private void DrawDragSplitter(int splitSize)
        {
            if (this._splitTarget != null)
            {
                Rectangle rectangle = this.CalculateSplitterLine(splitSize, 3);
                IntPtr parentHandlePointer = this.ParentInternalG.Handle;
                IntPtr parentDCPointer = UnsafeNativeMethods.GetDCEx(new HandleRef(this.ParentInternalG, parentHandlePointer), NativeMethods.NullHandleRef, 0x402);
                try
                {
                    IntPtr brushPointer = PaintControl.CreateHalftoneHBRUSH();
                    try
                    {
                        IntPtr parentPaintDCPointer = SafeNativeMethods.SelectObject(new HandleRef(this.ParentInternalG, parentDCPointer), new HandleRef(null, brushPointer));
                        SafeNativeMethods.PatBlt(new HandleRef(this.ParentInternalG, parentDCPointer), rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height, 0x5a0049);
                        SafeNativeMethods.SelectObject(new HandleRef(this.ParentInternalG, parentDCPointer), new HandleRef(null, parentPaintDCPointer));

                    }
                    catch
                    {
                        throw;

                    }
                    finally
                    {
                        SafeNativeMethods.DeleteObject(new HandleRef(null, brushPointer));

                    }

                }
                catch
                {
                    throw;

                }
                finally
                {
                    UnsafeNativeMethods.ReleaseDC(new HandleRef(this.ParentInternalG, parentHandlePointer), new HandleRef(null, parentDCPointer));

                }

            }

        }

        private Control FindTarget()
        {
            Control parent = this.ParentInternalG;
            if (parent != null)
            {
                Control.ControlCollection controlCollection = parent.Controls;
                int controlCount = controlCollection.Count;
                DockStyle dockStyle = this.Dock;

                for (int i = 0; i < controlCount; i++)
                {
                    Control control = controlCollection[i];
                    if (control != this)
                    {
                        switch (dockStyle)
                        {
                            case DockStyle.Top:
                                if (control.Bottom == base.Top)
                                {
                                    return control;

                                }
                                break;

                            case DockStyle.Bottom:
                                if (control.Top == base.Bottom)
                                {
                                    return control;

                                }
                                break;

                            case DockStyle.Left:
                                if (control.Right == base.Left)
                                {
                                    return control;

                                }
                                break;

                            case DockStyle.Right:
                                if (control.Left == base.Right)
                                {
                                    return control;

                                }
                                break;

                        }

                    }

                }

            }

            return null;

        }

        private int GetSplitterSize(int x, int y)
        {
            int start;
            if (this.Horizontal)
            {
                start = x - this._anchor.X;

            }
            else
            {
                start = y - this._anchor.Y;

            }

            int end = 0;
            switch (this.Dock)
            {
                case DockStyle.Top:
                    end = this._splitTarget.Height + start;
                    break;

                case DockStyle.Bottom:
                    end = this._splitTarget.Height - start;
                    break;

                case DockStyle.Left:
                    end = this._splitTarget.Width + start;
                    break;

                case DockStyle.Right:
                    end = this._splitTarget.Width - start;
                    break;

            }

            return Math.Max(Math.Min(end, this._maxSize), this._minSize);

        }

        /// <summary>
        /// Releases the unmanaged resources used by the GradientSplitter and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            try
            {
                if (!this._disposed)
                {
                    if (disposing)
                    {
                        this._gradientSplitBarRender.Dispose();

                    }

                }

                this._disposed = true;

            }
            catch
            {
                throw;

            }
            finally
            {
                base.Dispose(disposing);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control Alpha property has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnAlphaChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnAlphaChanged(System.EventArgs e)
        {
            if (this.AlphaChanged != null)
            {
                this.AlphaChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control antialias has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnAntiAliasChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnAntiAliasChanged(EventArgs e)
        {
            if (this.AntiAliasChanged != null)
            {
                this.AntiAliasChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control Border has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnBorderChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnBorderChanged(EventArgs e)
        {
            if (this.BorderChanged != null)
            {
                this.BorderChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control bump count has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnBumpCountChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnBumpCountChanged(EventArgs e)
        {
            if (this.BumpCountChanged != null)
            {
                this.BumpCountChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control CornerRadius has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnCornerRadiusChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnCornerRadiusChanged(EventArgs e)
        {
            if (this.CornerRadiusChanged != null)
            {
                this.CornerRadiusChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control BorderColor has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnBorderColorChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnBorderColorChanged(EventArgs e)
        {
            if (this.BorderColorChanged != null)
            {
                this.BorderColorChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control GradientMode has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnGradientModeChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnGradientModeChanged(EventArgs e)
        {
            if (this.GradientModeChanged != null)
            {
                this.GradientModeChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control gradient high color has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnGradientHighColorChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnGradientHighColorChanged(EventArgs e)
        {
            if (this.GradientHighColorChanged != null)
            {
                this.GradientHighColorChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control gradient low color has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnGradientLowColorChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnGradientLowColorChanged(EventArgs e)
        {
            if (this.GradientLowColorChanged != null)
            {
                this.GradientLowColorChanged(this, e);

            }

        }

        /// <summary>
        /// This method is not used in this class.
        /// </summary>
        /// <param name="e">A <see cref="T:System.Windows.Forms.KeyEventArgs"></see> that contains the event data.</param>
        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);

            if ((this._splitTarget != null) && (e.KeyCode == Keys.Escape))
            {
                this.EndMove(false);

            }

        }

        /// <summary>
        /// Raises the <see cref="E:System.Windows.Forms.Control.MouseDown"></see> event.
        /// </summary>
        /// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs"></see> that contains the event data.</param>
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);

            if ((e.Button == MouseButtons.Left) && (e.Clicks == 1))
            {
                this.BeginMove(e.X, e.Y);

            }

        }

        /// <summary>
        /// Raises the <see cref="E:System.Windows.Forms.Control.MouseMove"></see> event.
        /// </summary>
        /// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs"></see> that contains the event data.</param>
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            if (this._splitTarget != null)
            {
                int x = e.X + base.Left;
                int y = e.Y + base.Top;

                Rectangle rectangle = this.CalculateSplitterLine(this.GetSplitterSize(e.X, e.Y), 0);
                int splitterX = rectangle.X;
                int splitterY = rectangle.Y;

                this.OnGradientSplitterMoving(new GradientSplitterEventArgs(x, y, splitterX, splitterY));

            }

        }

        /// <summary>
        /// Raises the <see cref="E:System.Windows.Forms.Control.MouseUp"></see> event.
        /// </summary>
        /// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs"></see> that contains the event data.</param>
        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);

            if (this._splitTarget != null)
            {
                this.EndMove(true);

            }

        }

        /// <summary>
        /// Raises the GradientSplitterMoved event.
        /// </summary>
        /// <param name="gsevent">A GradientSplitterEventArgs that contains the event data.</param>
        protected virtual void OnGradientSplitterMoved(GradientSplitterEventArgs gsevent)
        {
            if (this.GradientSplitterMoved != null)
            {
                this.GradientSplitterMoved(this, gsevent);

            }

            if (this._splitTarget != null)
            {
                this.SplitMove(gsevent.SplitX, gsevent.SplitY);

            }

        }

        /// <summary>
        /// Raises the GradientSplitterMoving event.
        /// </summary>
        /// <param name="gsevent">A GradientSplitterEventArgs that contains the event data.</param>
        protected virtual void OnGradientSplitterMoving(GradientSplitterEventArgs gsevent)
        {
            if (this.GradientSplitterMoving != null)
            {
                this.GradientSplitterMoving(this, gsevent);

            }

            if (this._splitTarget != null)
            {
                this.SplitMove(gsevent.SplitX, gsevent.SplitY);

            }

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="specified"></param>
        protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
        {
            if (this.Horizontal)
            {
                if (width < 1)
                {
                    width = 3;

                }

                this._splitterThickness = width;

            }
            else
            {
                if (height < 1)
                {
                    height = 3;

                }

                this._splitterThickness = height;

            }

            base.SetBoundsCore(x, y, width, height, specified);

        }

        /// <summary>
        /// Raises the Paint event.
        /// </summary>
        /// <param name="e">A <see cref="T:System.Windows.Forms.PaintEventArgs"></see> that contains the event data.</param>
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            if (!this.Disposing)
            {
                base.OnPaint(e);

                if (this._showBackground)
                {
                    Rectangle rectangle = new Rectangle(0, 0, this.Width, this.Height);
                    this._gradientSplitBarRender.DisplayRectangle = rectangle;

                    this._gradientSplitBarRender.Render(e);

                }

            }

        }

        private void BeginMove(int x, int y)
        {
            GradientSplitterData gradientSplitterData = this.CalculateSplitterBounds();

            if ((gradientSplitterData.target != null) && (this._minSize < this._maxSize))
            {
                this._anchor = new Point(x, y);
                this._splitTarget = gradientSplitterData.target;
                this._splitterSize = this.GetSplitterSize(x, y);

                InternalSecurity.UnmanagedCode.Assert();
                try
                {
                    if (this._gradientSplitterMessageFilter != null)
                    {
                        this._gradientSplitterMessageFilter = new GradientSplitterMessageFilter(this);

                    }

                    Application.AddMessageFilter(this._gradientSplitterMessageFilter);

                }
                catch
                {
                    throw;

                }
                finally
                {
                    CodeAccessPermission.RevertAssert();

                }

                this.HasMouseCapture = true;
                this.DrawSplitterBar(DRAW_SPLITTER_START);

            }

        }

        private void EndMove(bool accept)
        {
            this.DrawSplitterBar(DRAW_SPLITTER_END);
            this._splitTarget = null;
            this.HasMouseCapture = false;

            if (this._gradientSplitterMessageFilter != null)
            {
                Application.RemoveMessageFilter(this._gradientSplitterMessageFilter);
                this._gradientSplitterMessageFilter = null;

            }

            if (accept)
            {
                this.SplitPosition = this._splitterSize;

            }
            else if (this._splitterSize != this._initTargetSize)
            {
                this.SplitPosition = this._initTargetSize;

            }

            this._anchor = Point.Empty;

        }

        private void SplitMove(int x, int y)
        {
            int splitterSize = this.GetSplitterSize((x - base.Left) + this._anchor.X, (y - base.Top) + this._anchor.Y);
            if (this._splitterSize != splitterSize)
            {
                this._splitterSize = splitterSize;
                this.DrawSplitterBar(DRAW_SPLITTER_MOVE);

            }

        }

        /// <summary>
        /// Returns a string that represents the GradientSplitter control.
        /// </summary>
        /// <returns>
        /// A string that represents the current GradientSplitter. 
        /// </returns>
        public override string ToString()
        {
            string text = base.ToString();
            return (text + ", MinExtra: " + this.MinExtra.ToString(CultureInfo.CurrentCulture) + ", MinSize: " + this.MinSize.ToString(CultureInfo.CurrentCulture));

        }

        private class GradientSplitterData
        {
            public int dockHeight;
            public int dockWidth;
            internal Control target;

            /// <summary>
            /// 
            /// </summary>
            public GradientSplitterData()
            {
                this.dockWidth = -1;
                this.dockHeight = -1;

            }

        }

        private class GradientSplitterMessageFilter : IMessageFilter
        {
            private GradientSplitter _owner;
            
            public GradientSplitterMessageFilter(GradientSplitter splitter)
            {
                this._owner = splitter;

            }

            [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
            public bool PreFilterMessage(ref Message m)
            {
                if ((m.Msg < 0x100) || (m.Msg > 0x108))
                {
                    return false;

                }
                if ((m.Msg == 0x100) && (((int)((long)m.WParam)) == 0x1b))
                {
                    this._owner.EndMove(false);

                }

                return true;

            }

        }

        /// <param name="e">An <see cref="T:System.EventArgs"></see> that contains the event data.</param>
        protected override void OnResize(System.EventArgs e)
        {
            base.OnResize(e);

            base.Invalidate();

        }

    }

}
